package com.gusto.engine.clusterant.algorithms.antsclustering.ants;

import java.util.List;

import com.gusto.engine.clusterant.algorithms.antsclustering.Neighbor;
import com.gusto.engine.clusterant.algorithms.antsclustering.Plan;

/**
 * <p>Ant with an improved movement behavior.</p>
 * 
 * @author amokrane.belloui@gmail.com
 *
 */
@Deprecated
public class AntImprovement extends Ant {
	
	protected Double minDistance; // INIT
	protected int directionRow = 0;
	protected int directionCol = 0;
	 
	protected int bestRow;
	protected int bestCol;
	protected double bestDist;
	
	public AntImprovement(Plan plan, long maxMoves, int maxMovesWithObject, Double minDistance) {
		super(plan, maxMoves, maxMovesWithObject);
		// Initialize objects
		this.minDistance = minDistance;
		// Set the direction
		changeDirectionRandom();
	}
	
	private int getRandom() {
		// Get a value between [-1; 0; +1]
		int r = Integer.parseInt(Math.round(Math.random() * 2) + "") - 1;
		return r;
	}
	
	public void changeDirectionRandom() {
		int newDirectionRow = getRandom();
		int newDirectionCol = getRandom();
		while (
				(newDirectionRow == 0 && newDirectionCol == 0) ||
				(directionRow + newDirectionRow + directionCol + newDirectionCol == 0) ||
				(directionRow == newDirectionRow && directionCol == newDirectionCol)
		) {
			newDirectionRow = getRandom();
			newDirectionCol = getRandom();
		}
		directionRow = newDirectionRow;
		directionCol = newDirectionCol;
		//log.debug("Direction change " + directionRow + " " + directionCol);
	}
	
	public void changeDirectionBest() {
		Double directionBestDist = 0D;
		for (int i = row - 1; i <= row + 1; i++) {
			for (int j = col - 1; j <= col + 1; j++) {
				if (i>=0 && i<plan.getRows() && j>=0 && j<plan.getCols()) {
					
					if (!(row == i && col == j)) {
						Double dist = plan.getSimilarityNeighbors(object, plan.getNeighbors(i, j, perception));
						if (dist > directionBestDist) {
							directionBestDist = dist;
							directionRow = row - i;
							directionCol = col - j;
						}
					}
					
				}
			}
		}
	}
	
	
	protected void move() {
		// If the movement gets the ant outside the plan, changeDirection
		while (
				((row + directionRow) < 0) ||
				((row + directionRow) >= plan.getRows()) ||
				((col + directionCol) < 0) ||
				((col + directionCol) >= plan.getCols())
		) {
			changeDirectionRandom();
			//if (hasPickedObject()) {
			//changeDirectionBest();
		}
		// Move according to the direction
		row = row + directionRow;
		col = col + directionCol;
	}
	
	protected void doPick() {
		Object objectOnPlan = plan.getObject(this.row, this.col);
		
		List<Neighbor> neighbors = plan.getNeighbors(this.row, this.col, this.perception); 
		Double dist = plan.getSimilarityNeighbors(objectOnPlan, neighbors);
		
		if ((dist < minDistance)) {
			bestRow = this.row;
			bestCol = this.col;
			bestDist = dist;
			pick();
			changeDirectionBest();
		}
	}
	
	protected void doDrop() {
		Double dist = plan.getSimilarityNeighbors(object, plan.getNeighbors(this.row, this.col, this.perception));
		
		if ( dist < bestDist ) {
			
			// Worse position, put in the best we've found
			//if ( bestDist >= minDistance ) {
				moveTo(bestRow, bestCol);
				drop();
				changeDirectionRandom();
			//}
			
		}
		else { // dist Defined && dist >= bestDist
			bestRow = this.row;
			bestCol = this.col;
			bestDist = dist;
		}
	}
	
	/*
	public void doForcedDrop() {
		moveTo(bestRow, bestCol);
		drop();
		changeDirectionRandom();
	}
	*/
}
